﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using ExcellOnServices.Models;
using PagedList;

namespace ExcellOnServices.Areas.DashBoard.Controllers
{
	public class OrdersController : Controller
	{
		private ExcellOnServicesContext db = new ExcellOnServicesContext();

		// GET: /DashBoard/Orders/
		[Authorize]
		public ActionResult Index(string searchFromDate = null, string searchToDate = null, string status = null, int page = 1) {
			int currentCompany = int.Parse(@User.Identity.Name);
			var orders = db.Orders.Where(o => o.OrderItems.FirstOrDefault().Product.Accounts_Company.Id == currentCompany);
			DateTime startDate = new DateTime();
			DateTime endDate = new DateTime();

			if (!String.IsNullOrEmpty(searchFromDate)) {
				startDate = DateTime.Parse(searchFromDate);
			}
			if (!String.IsNullOrEmpty(searchToDate)) {
				endDate = DateTime.Parse(searchToDate);
			}
			if (String.IsNullOrEmpty(searchFromDate) && !String.IsNullOrEmpty(searchToDate)) {
				orders = orders.Where(s => s.BeginDateTime <= endDate);
			} else if (!String.IsNullOrEmpty(searchFromDate) && String.IsNullOrEmpty(searchToDate)) {
				orders = orders.Where(s => s.BeginDateTime >= startDate);
			} else if (!String.IsNullOrEmpty(searchFromDate) && !String.IsNullOrEmpty(searchToDate)) {
				orders = orders.Where(s => s.BeginDateTime >= startDate && s.BeginDateTime <= endDate);
			}
			if (!String.IsNullOrEmpty(status)) {
				int statusID = (int)Enum.Parse(typeof(Order.StatusOrder), status);
				orders = orders.Where(s => (int)s.Status == statusID);
			}
			IEnumerable<Order.StatusOrder> statusList = Enum.GetValues(typeof(Order.StatusOrder)).OfType<Order.StatusOrder>();

			ViewBag.Status = new SelectList(statusList);
			ViewBag.StatusName = status;
			ViewBag.SearchFromDate = searchFromDate;
			ViewBag.SearchToDate = searchToDate;
			ViewBag.Page = page;

			return View(orders.OrderBy(s => s.Status).ThenByDescending(s => s.ModifiedDateTime).Select(s => s).ToPagedList(page, 10));
		}

		// GET: /DashBoard/Orders/Details/5
		[Authorize]
		public ActionResult Details(int? id) {
			if (id == null) {
				return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
			}
			Order order = db.Orders.Find(id);
			if (order == null) {
				return HttpNotFound();
			}
			return View(order);
		}

		// GET: /DashBoard/Orders/Create
		[Authorize]
		public ActionResult Create() {
			ViewBag.Products = ListProductForOrder();
			ViewBag.Services = db.Services.ToList();
			ViewBag.SelectServices = new SelectList(db.Services.ToList(), "Id", "Name");
			ViewBag.SelectCategories = new SelectList(db.Categories.ToList(), "Id", "Name");
			return View();
		}

		// POST: /DashBoard/Orders/Create
		// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
		// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
		[HttpPost]
		[ValidateAntiForgeryToken]
		[Authorize]
		public ActionResult Create([Bind(Include = "Id,BeginDateTime,EndDateTime,Payment")] Order order, ICollection<OrderItem> orderItems) {
			try {
				bool isValid = true;

				if (order.BeginDateTime.Date < DateTime.Now.Date) {
					// Validate Begin Datetime
					ModelState.AddModelError("", "Begin date must be later than or the same time as the date today!");
					isValid = false;
				} else if (order.BeginDateTime > order.EndDateTime) {
					// Validate Datetime
					ModelState.AddModelError("", "Begin date must be earlier than end date!");
					isValid = false;
				} else if (orderItems == null) {
					ModelState.AddModelError("", "Orders must have product and products must have choosen service!");
					isValid = false;
				}

				if (!isValid) {
					ViewBag.Products = ListProductForOrder();
					ViewBag.Services = db.Services.ToList();
					ViewBag.SelectServices = new SelectList(db.Services.ToList(), "Id", "Name");
					ViewBag.SelectCategories = new SelectList(db.Categories.ToList(), "Id", "Name");
					ViewBag.OrderItems = orderItems;
					return View(order);
				}

				db.Orders.Add(order);
				db.SaveChanges();

				var services = db.Services.ToList();

				foreach (OrderItem item in orderItems) {
					item.ServicePrice = services.Where(s => s.Id == item.Service_Id).FirstOrDefault().Price;
					item.Order_Id = order.Id;
					db.OrderItems.Add(item);
				}
				db.SaveChanges();
				return RedirectToAction("Index");
			} catch (DataException ex) {
				ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator." + ex.Message);
			}
			ViewBag.Products = ListProductForOrder();
			ViewBag.SelectServices = new SelectList(db.Services.ToList(), "Id", "Name");
			return View(order);
		}

		public List<Product> ListProductForOrder() {
			int id = int.Parse(User.Identity.Name);
			var products = (from p in db.Products
							where p.Company_Id == id
							orderby p.ModifiedDateTime descending
							select p).ToList();
			return products;
		}

		public ActionResult GetAjaxProducts(string search = null, int? categoryId = null) {
			int id = int.Parse(User.Identity.Name);
			var products = (from p in db.Products
							where p.Company_Id == id
							orderby p.ModifiedDateTime descending
							select p).ToList();

			if (search != null) {
				products = (from p in products
							where p.Name.ToLower().Contains(search.Trim().ToLower())
							select p).ToList();
			}

			if (categoryId != null) {
				products = (from p in products
							where p.Category_Id == categoryId
							select p).ToList();
			}

			ViewBag.Products = products;
			return View("_PartialAjaxProducts");
		}

		// GET: /DashBoard/Orders/Delete/5
		[Authorize]
		[ActionName("Delete")]
		public ActionResult Delete(int? id, string searchFromDate, string searchToDate, string status, int page = 1) {
			if (id == null) {
				return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
			}
			Order order = db.Orders.Find(id);
			if (order == null) {
				return HttpNotFound();
			}
			db.Orders.Remove(order);
			db.SaveChanges();
			return RedirectToAction("Index", new { searchFromDate = searchFromDate, searchToDate = searchToDate, status = status, page = page });
		}

		protected override void Dispose(bool disposing) {
			if (disposing) {
				db.Dispose();
			}
			base.Dispose(disposing);
		}
	}
}
